<body>
    H8A8 generates hibernate mapping xml files from java classes that are annotated with special java annotations.
    The mapping xml files can be generated at compile time or runtime and used to configure hibernate.

    <h2>Installation</h2>
    The peelmeagrape-hibernate.jar contains all the annotation definitions as well as hibernate configuration tools
    and ant tasks. This jar needs to be on the classpath at runtime. It has dependencies on:
    <ul>
        <li>Dom4J - required for xml generation</li>
        <li>commons-logging - required</li>
        <li>hibernate3 - required</li>
        <li>spring - optional (required for {@link net.peelmeagrape.hibernate.config.LocalSessionFactoryBean})</li>
    </ul>

    <h2>Configuration</h2>
    <h3>Spring Configuration</h3>
    There is a subclass of Spring's {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean}
    that adds a List&lt;Class&gt; property:
    <pre>
        &lt;bean id="sessionFactory" class="net.peelmeagrape.hibernate.LocalSessionFactoryBean"&gt;
            &lt;property name="annotatedClasses"&gt;
                &lt;list&gt;
                    &lt;value&gt;net.peelmeagrape.hibernate.SimpleEntity&lt;/value&gt;
                &lt;/list&gt;
            &lt;/property&gt;
            &lt;property name="hibernateProperties"&gt;
                &lt;props&gt;
                    &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/prop&gt;
        ....
    </pre>

    Alternatively, you can use the normal {@link org.springframework.orm.hibernate3.LocalSessionFactoryBean}
    with a customized {@link org.hibernate.cfg.Configuration} ({@link net.peelmeagrape.hibernate.config.HibernateConfiguration}):
    <pre>
        &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt;
            &lt;property name="configurationClass"&gt;
                &lt;value&gt;net.peelmeagrape.hibernate.config.HibernateConfiguration&lt;/value&gt;
            &lt;/property&gt;
            &lt;property name="configLocation"&gt;
                &lt;value&gt;net/peelmeagrape/hibernate/HibernateConfigurationTest_hibernate.xml&lt;/value&gt;
            &lt;/property&gt;
            &lt;property name="hibernateProperties"&gt;
                &lt;props&gt;
                    &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.HSQLDialect&lt;/prop&gt;
    </pre>
    in this case, you use a hibernate configuration file to specify the annotated classes:
    <pre>
        &lt;!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

        &lt;hibernate-configuration>
            &lt;session-factory>
                &lt;mapping class="net.peelmeagrape.hibernate.example.SimpleEntity"/>
            &lt;/session-factory>
        &lt;/hibernate-configuration>
    </pre>

    <h3>Compile Time Generation</h3>
    You can use the annotated classes to generate hibernate xml mapping files at compile time.
    The task must have a classpath configured (which it will use to load the classes and read
    their annotations). The task needs a fileset to operate on. This can be either the sourcecode
    or class files - the matched file names are converted to class names. e.g., in this example
    the file <code>output/classes/some/package/SomeEntity.class</code> will be mapped to the classname
    <code>some.package.SomeEntity</code> and will generate the mapping file
    <code>output/hibernate/some/package/SomeEntity.hbm.xml</code>.
    <pre>
    &lt;hibernate-mappings destdir="output/hibernate" srcdir="output/classes">
            &lt;include name="**/*.class"/>
            &lt;classpath>
                &lt;pathelement location="output/classes"/>
                &lt;fileset dir="lib" includes="**/*.jar"/>
            &lt;/classpath>
        &lt;/hibernate-mappings>
    </pre>
    Assuming you've put the h8a8 jar file into the <code>lib/hibernate</code> folder, the taskdef can be
    made as follows:
    <pre>
        &lt;taskdef resource="net/peelmeagrape/hibernate/ant/tasks.properties">
            &lt;classpath>
                &lt;fileset dir="lib" includes="hibernate/*.jar"/>
            &lt;/classpath>
        &lt;/taskdef>
    </pre>

    <h3>Programmatic configuration</h3>
    {@link net.peelmeagrape.hibernate.config.HibernateConfiguration} extends the standard Hibernate {@link org.hibernate.cfg.Configuration}
    class with an {@link net.peelmeagrape.hibernate.config.HibernateConfiguration#addAnnotatedClass} method.

    <h2>Using the annotations</h2>
    <p>All the annotations are in the {@link net.peelmeagrape.hibernate} package and subpackages. Each annotation corresponds
    to an xml element in the generated xml.
    The <a href="{@docRoot}/reference/en/html/mapping.html">Hibernate mapping documentation</a> should be considered the definitive reference on the
    meaning of the generated xml elements and attributes.</p>
    <h3>Simple Examples</h3>
    <p>Simple Entity:</p>
    <pre>
        &#64;{@link net.peelmeagrape.hibernate.H8Class}
        class MyEntity
        {
            &#64;{@link net.peelmeagrape.hibernate.Id} public String id;
        }
    </pre>

    <p>Mapping a set:</p>
    <pre>
        &#64;{@link net.peelmeagrape.hibernate.collections.H8Set}(
            key=&#64;{@link net.peelmeagrape.hibernate.collections.Key}(),
            value=@CollectionValue(otm = &#64;{@link net.peelmeagrape.hibernate.collections.OneToMany})
        )
        public Set&lt;String> items;
    </pre>
    <h3>Notes</h3>
    <ul>
        <li>Java annotations do not allow '<code>null</code>' as a default value. Optional members of an
        annotation (for non-primitives) are specified as an array with a default value of <code>{}</code>
        </li>
        <li></li>
        <li>
            Some annotations add extra xml attributes based on the element being annotated (e.g. the
            class name, property name or property type).
        </li>
        <li>
            Some annotations can add extra information to the xml based on the generic type of the
            element being annotated. e.g.:
            <pre>
        &#64;{@link net.peelmeagrape.hibernate.collections.H8Map}(
            key=&#64;{@link net.peelmeagrape.hibernate.collections.Key}(column = "parentEntity"),
            mapKey= &#64;{@link net.peelmeagrape.hibernate.collections.MapKey}(mapKey = &#64;{@link net.peelmeagrape.hibernate.collections.SimpleMapKey}(column="name")),
            value=&#64;{@link net.peelmeagrape.hibernate.collections.CollectionValue}(otm = &#64;{@link net.peelmeagrape.hibernate.collections.OneToMany})
        )
        public Map&lt;String,Integer> items;
            </pre>
            would generate the xml:
            <pre>
        &lt;map name="items">
          &lt;key column="parentEntity"/>
          &lt;map-key column="name" type="java.lang.String"/>
          &lt;one-to-many class="java.lang.Integer"/>
        &lt;/map>
            </pre>
            In this example, <code>name="items"</code> was generated from the field name. The
            <code>map-key</code> <i>type</i> attribute was generated from the generic 'key' type
            of the map, and the <code>one-to-many</code> type from the generic 'value' type of
            the map.
        </li>
        <li>
            Some annotations cause another class to be processed and have it's annotations added
            to the current position in the xml. e.g. a
            {@link net.peelmeagrape.hibernate.CompositeId} annotation on a field will cause the
            type of that field to be processed:
            <code>&#64;{@link net.peelmeagrape.hibernate.CompositeId} private CompIdType name;</code> will cause the
            <code>CompIdType</code> class's fields and methods to be scanned:
            <pre>
        class CompIdType
        {
            &#64;{@link net.peelmeagrape.hibernate.collections.KeyProperty} public String firstName;
            &#64;{@link net.peelmeagrape.hibernate.collections.KeyProperty} public String surname;
        }
            </pre>
        </li>
        <li>
            Most annotations are intended to apply to an entity's class definition or it's properties.
            Some annotations, however, can be specified on any element with global effect - queries for
            example:
            <pre>
        &#64;{@link net.peelmeagrape.hibernate.Query}(name="query", query="select * from Entity")
        private int void doSomeQuery()
        {
            //hibernate code using the named query 'query'
        }
            </pre>
            In this case, the DAO class (or whatever class declaring the query) would be added to
            the hibernate configuration, even though it is not an entity class.
        </li>
    </ul>

    <h3>Unsupported Mappings</h3>
    H8A8 can currently (I think - let me know if I've missed any) generate any mapping allowed by the hibernate3
    dtd with the exception of:
    <ul>
        <li>&lt;dynamic-component&gt; elements</li>
    </ul>

    <h2>Todo</h2>
    <ul>
        <li>Generate the hibernate configuration xml file from an ant task (list all classes that
        are annotated)</li>
        <li>As above, generate spring xml configuration</li>
        <li>Schema generation from ant task (useful way to understand what the mapping is doing)</li>
        <li>Document annotations (bring appropriate documentation from hibernate reference, convert examples from xml into annotations).</li>
        <li>Hibernate 2 support?</li>
    </ul>

    <h2>License</h2>
    H8A8 is released under a <a href="{@docRoot}/h8a8.license.txt">BSD License</a>.
</body>
